package com.gjp.utils;

import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by 郭金鹏 on 2018/6/9.
 * JWT Java Web Token
 */
public class JWT {

    //加密密钥 key
    private static final String SECRET = "!@#WERWE3423WEW#$%yry5YERY3634$WY346345@%@#tt2R@#rgweT@tt";
    //过期时间 key 名
    private static final String EXP = "exp";
    //用户信息 key名
    private static final String PAYLOAD = "payload";

    /**
     * 返回jwt token,根据传入对象，并设置过期时间
     *
     * @param object the POJO object
     * @param maxAge the milliseconds of life time
     * @return the jwt token
     */
    public static <T> String sign(T object, long maxAge) {
        try {
            //根据SECRET加密串，创建JWTSigner对象
            final JWTSigner signer = new JWTSigner(SECRET);
            //创建claims集合，放入jwt中加密
            final Map<String, Object> claims = new HashMap<>();
            //将传入的数据序列化为json字符串
            String jsonString = new ObjectMapper().writeValueAsString(object);
            //把数据放入claims中
            claims.put(PAYLOAD, jsonString);
            //设置过期时间
            claims.put(EXP, System.currentTimeMillis() + maxAge);
            //生成token并返回
            return signer.sign(claims);
        } catch (Exception e) {
            //加密失败
            return null;
        }
    }


    /**
     * get the object of token if not expired
     * 如果JWT没有过期，解码JWT中的数据返回
     *
     * @param token 加密token
     * @return POJO object  返回用户数据
     */
    public static <T> T unsign(String token, Class<T> classT) {
        try {
            final JWTVerifier verifier = new JWTVerifier(SECRET);
            final Map<String, Object> claims = verifier.verify(token);
            if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
                long exp = (Long) claims.get(EXP);
                long currentTimeMillis = System.currentTimeMillis();
                //如果过期时间大于当前时间，代表没有过期
                if (exp > currentTimeMillis) {
                    String json = (String) claims.get(PAYLOAD);
                    //将json序列化为对象并返回
                    return new ObjectMapper().readValue(json, classT);
                }
            }
            //解密失败
            return null;
        } catch (Exception e) {
            return null;
        }
    }
}
